package pt.fct.mpc.rfbul;

import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import pt.fct.mpc.rfbul.database.MapperDatabaseAdapter;
import pt.fct.mpc.rfbul.database.MapperDatabaseEntry;
import pt.fct.mpc.rfbul.misc.MapperConstants;
import pt.fct.mpc.rfbul.misc.PositionDevice;
import pt.fct.mpc.rfbul.misc.PositionHandling;
import pt.fct.mpc.rfbul.test.TestOfflineActivity;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.AsyncTask.Status;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity 
	extends Activity 
{
	private static final String TAG = "RFBUL";
	private static final String SSID_TO_LOOK_FOR = "eduroam";
	private ProgressDialog progress_dialog = null;
	List<ScanResult> results = null;
	private WifiManager wifi_manager;
	
	private Handler handler = new Handler();
	
	private BroadcastReceiver receiver_results = 
		new BroadcastReceiver()
		{
			@Override
			public void onReceive(Context context, Intent intent)
			{
				if (intent.getAction().equals(
					WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))
				{
					results = wifi_manager.getScanResults();
					
					if ((progress_dialog != null) 
						&& (progress_dialog.isShowing()))
					{
						progress_dialog.dismiss();
					}
					
					handler.post(
						new Runnable()
						{
							@Override
							public void run()
							{
								doResultsHandling();

							}
						});
				}
			}
		};
	private Button view_button_get_position;
	private Button view_button_mapper;
	private Button view_button_test;
	protected Context context;
	
	private OnClickListener listener_button =
		new OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				Intent intent;
				switch (v.getId())
				{
					case R.id.layout_main_button_get_position:
						
						doGetPosition();
						
						break;
						
					case R.id.layout_main_button_map:
						
						intent = new Intent(context, MapperActivity.class);
				        startActivity(intent);
				        
						break;
						
					case R.id.layout_main_button_test:
						
						intent =
							new Intent(context, TestOfflineActivity.class);
						startActivity(intent);
						
						break;
				}
				
			}
		};
	private FindPositionTask task_find_position = null;
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.rfbul_main);

        this.context = this;
        
        this.view_button_get_position =
        	(Button) findViewById(R.id.layout_main_button_get_position);
        this.view_button_mapper =
        	(Button) findViewById(R.id.layout_main_button_map);
        this.view_button_test = 
        	(Button) findViewById(R.id.layout_main_button_test);
        
        this.view_button_get_position.setOnClickListener(listener_button);
        this.view_button_mapper.setOnClickListener(listener_button);
        this.view_button_test.setOnClickListener(listener_button);
    }


	protected void doGetPosition()
	{
		wifi_manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        
        if (!wifi_manager.isWifiEnabled())
        {
        	if (wifi_manager.getWifiState() != WifiManager.WIFI_STATE_ENABLING)
        		wifi_manager.setWifiEnabled(true);
        }

        wifi_manager.createWifiLock(WifiManager.WIFI_MODE_SCAN_ONLY, TAG);

        registerReceiver(receiver_results, 
        	new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
        
        
        this.progress_dialog = new ProgressDialog(this);
        this.progress_dialog.setMessage("Scanning...");
        this.progress_dialog.show();
        
        wifi_manager.startScan();
	
	}


	private void doResultsHandling()
	{
		unregisterReceiver(receiver_results);
		
		if (this.results == null)
			return;
		
		if (this.results.size() == 0)
		{
			// no results
			return;
		}
		
		LinearLayout view_layout_position =
			(LinearLayout) findViewById(R.id.layout_main_layout_position);
		view_layout_position.setVisibility(View.VISIBLE);
		
		ArrayAdapter<String> results_adapter = 
			new ArrayAdapter<String>(getApplicationContext(), 
				R.layout.rfbul_list_item);
		
		for (ScanResult r : this.results)
		{
			if (r.SSID.equalsIgnoreCase(SSID_TO_LOOK_FOR) == false)
				continue;
			
			String str = r.SSID + "\n" + r.BSSID + "\n" + r.level;
			
			results_adapter.add(str);
		}
		
		ListView lv = (ListView) findViewById(R.id.layout_main_list_scan);
		lv.setAdapter(results_adapter);
		
		doFindPosition();
	}

	class FindPositionTask 
		extends AsyncTask<Void, Void, MapperDatabaseEntry>
	{
		MapperDatabaseAdapter db_adapter = null;
		
		@Override
		protected void onPreExecute()
		{
			super.onPreExecute();

			progress_dialog = new ProgressDialog(context);
			progress_dialog.setMessage("Acquiring Position...");
			progress_dialog.show();
		}

		@Override
		protected MapperDatabaseEntry doInBackground(Void... params)
		{
			PositionHandling handler = new PositionHandling(context);
			
			Set<PositionDevice> devices = PositionDevice.getSetBySSID(results, 
				MapperConstants.SSID_TO_LOOK_FOR);
			return handler.doFindPosition(devices);
		}
		
		@Override
		protected void onPostExecute(MapperDatabaseEntry result)
		{
			if ((progress_dialog != null) && (progress_dialog.isShowing()))
				progress_dialog.dismiss();
			
			doHandlePosition(result);
		}
		
		@Override
		protected void onCancelled()
		{
			super.onCancelled();
		}
	}

	private void doFindPosition()
	{
		if (this.task_find_position != null)
		{
			Status status = this.task_find_position.getStatus();
			if (status == Status.PENDING)
				this.task_find_position.cancel(true);
			else
			{
				ProgressDialog wait_finished_dialog = 
					new ProgressDialog(context);
				wait_finished_dialog.setMessage("We must wait a bit...");
				wait_finished_dialog.show();
				while (this.task_find_position.getStatus() != Status.FINISHED);
				wait_finished_dialog.dismiss();
			}
		}
		this.task_find_position = new FindPositionTask();
		this.task_find_position.execute();
		
	}


	protected void doHandlePosition(MapperDatabaseEntry best_match)
	{
		if (best_match == null)
		{
			Toast.makeText(context, "Best Match is null", 
				Toast.LENGTH_SHORT).show();
			return;
		}
		
		
		TextView tv = 
			(TextView) findViewById(R.id.layout_main_text_current_pos);
		tv.setText("Current Position: "+best_match.room 
			+ " ("+best_match.rel_pos+")");
		tv.setVisibility(View.VISIBLE);
	}
}